home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************************
- *
- *
- * Edit Field Library- .h Definition File
- *
- * 9/9/92 ©ImproVision UK. Written by Graham Cox.
- *
- ****************************************************************************************/
-
-
- #include "EditFields.h"
-
-
- extended
- GPCstr2num(void *s)
- {
- short n = 1;
- char p = 0;
- decimal d;
- extended x;
-
- decstr68k(s, &n, &d, &p, FPSTR2DEC);
- fp68k(&d, &x, FDEC2X);
- return(x);
- }
-
-
- void
- GPCnum2str(decform *f, extended x, void *s)
- {
- decimal d;
-
- fp68k(f, &x, &d, FX2DEC);
- decstr68k(f, &d, s, FDEC2STR);
- }
-
-
- CopyString(Ptr s1,Ptr s2)
- {
- short byteCount;
-
- byteCount=*s1+1;
- BlockMove(s1,s2,byteCount);
- }
-
-
- ConcatString(Ptr s1,Ptr s2)
- {
- /* given pointers to two pascal strings, this function concatenates the characters of
- s2 on to the end of s1. No range checking is performed. */
-
- short byteCount,offset;
- Ptr temp;
-
- temp=s1; /* remember old pointer */
- offset=*s1+1; /* length of first string */
- s1+=offset; /* point at end of string +1 */
- byteCount=*s2; /* length of second string */
- s2++; /* first char of second string */
- BlockMove(s2,s1,byteCount); /* copy chars */
- *temp=offset+byteCount-1; /* update length */
- }
-
-
- EditFieldHdl NewEditField(Rect *bounds,int IDnum,Str255 *theText)
- {
- /* creates a new edit field record with the given parameters. The record is not
- automatically linked to the fields list- you have to do this */
-
- EditFieldHdl temp;
-
- temp = (EditFieldHdl) NewHandleClear(sizeof(EditField));
- if (temp != NIL) {
- (*temp)->efID = IDnum;
- (*temp)->edViewRect = *bounds;
- (*temp)->edFlags = fieldNoRestriction;
- (*temp)->upLimit = 256;
- (*temp)->lowLimit = 1;
- HLock((Handle) temp);
- CopyString((Ptr)theText,(Ptr)&(*temp)->edFieldText);
- HUnlock((Handle) temp);
- (*temp)->nextField = NIL;
- }
- return(temp);
- }
-
-
- void LinkEditField(EFListHdl efList,EditFieldHdl eField)
- {
- /* pushes the given eField onto the top of the stack of fields in the main struct */
-
- if (efList != NIL && eField != NIL) {
- (*eField)->nextField = (*efList)->efListHead;
- (*efList)->efListHead = eField;
- }
- }
-
-
- void Draw1Field(EditFieldHdl theField)
- {
- /* draws the given field using TextBox */
-
- Rect tView,tFrame;
-
- if (theField != NIL) {
- tView = (*theField)->edViewRect;
- tFrame = tView;
- InsetRect(&tFrame,-3,-3);
- FrameRect(&tFrame);
-
- HLock((Handle) theField);
- TextBox(&(*theField)->edFieldText[1],
- (*theField)->edFieldText[0],
- &tView,
- teJustLeft);
-
- HUnlock((Handle) theField);
- }
- }
-
-
- void SetFieldText(EditFieldHdl theField,Str255 *theText)
- {
- /* sets the text in the given field to the supplied string. To update the display,
- you will need to do more! */
-
- if (theField != NIL) {
- CopyString((Ptr)theText,(Ptr)&(*theField)->edFieldText);
- (*theField)->edFlags |= fieldDataChanged;
- }
- }
-
-
- void GetFieldText(EditFieldHdl theField,Str255 *theText)
- {
- /* returns the string in the associated field */
-
- if (theField != NIL)
- CopyString((Ptr)&(*theField)->edFieldText,(Ptr)theText);
- }
-
-
- void SetFPField(EditFieldHdl theField,extended fpValue,int nDecPlaces)
- {
- /* converts the given floating point value to a string with the given number of
- decimal places, then sets the text of the field to this string. */
-
- DecForm fpFormat;
- Str255 fpText;
-
- if (theField != NIL) {
- fpFormat.style = FIXEDDECIMAL;
- fpFormat.digits = nDecPlaces;
-
- GPCnum2str(&fpFormat,fpValue,&fpText);
- SetFieldText(theField,&fpText);
-
- }
- }
-
-
- extended GetFPField(EditFieldHdl theField)
- {
- /* converts the given field's text string to a floating point value. */
-
- Str255 fpText;
-
- if (theField != NIL) {
- GetFieldText(theField,&fpText);
- return(GPCstr2num(&fpText));
- }
- }
-
-
- void SetEdFlags(EditFieldHdl theField,long theFlags)
- {
- /* sets the flags field to the given value */
-
- if (theField != NIL)
- (*theField)->edFlags = theFlags;
- }
-
-
- long GetEdFlags(EditFieldHdl theField)
- {
- /* returns the field flags field */
-
- if (theField != NIL)
- return((*theField)->edFlags);
- else
- return(-1L);
- }
-
-
- EFListHdl NewEditFieldList(WindowPtr ownerWindow)
- {
- /* creates a new edit field list record, preinitialised with the owner window, and a
- new TERecord incorporating the ownerWindow's grafPort. No fields are yet attached
- to the record- these are created with NewEditField and linked with LinkEditField */
-
- EFListHdl temp;
- GrafPtr savePort;
- Rect tRect;
-
- temp = (EFListHdl)NewHandleClear(sizeof(EFList));
- if (temp != NIL) {
- (*temp)->efOwner = ownerWindow;
- (*temp)->numFields = 0;
- (*temp)->currentField = 0;
- (*temp)->efListHead = NIL;
- GetPort(&savePort);
- SetPort(ownerWindow);
-
- tRect = ownerWindow->portRect;
- (*temp)->efText = TENew(&tRect,&tRect);
-
- SetPort(savePort);
- }
- return(temp);
- }
-
-
- void DisposeEditFieldList(EFListHdl theList)
- {
- /* disposes of ef list and all internal structures */
-
- EditFieldHdl temp,efNext;
-
- if (theList != NIL) {
-
- temp = (*theList)->efListHead;
-
- while (temp != NIL) {
- efNext = (*temp)->nextField;
- DisposHandle(temp);
- temp = efNext;
- }
-
- TEDispose((*theList)->efText);
-
- DisposHandle(theList);
- }
- }
-
-
- EditFieldHdl GetIndexedField(EFListHdl efList,int theIndex)
- {
- /* returns the handle of the edit field record having the ID number theIndex. If
- the index does not exist in the list, NIL is returned */
-
- EditFieldHdl temp = NIL;
-
- if (efList != NIL) {
- temp = (*efList)->efListHead;
- while (temp != NIL) {
- if ((*temp)->efID == theIndex)
- break;
- else
- temp = (*temp)->nextField;
- }
- }
- return(temp);
- }
-
-
- void IncDecCurrentField(EFListHdl efList,Boolean incDecFlag)
- {
- /* increment or decrements currently selected edit field. This is designed to be
- called repeatedly in a loop, and uses a delay to avoid this occurring too fast. */
-
- long tDelay,fValue,efFlags,uLimit,lLimit;
- EditFieldHdl theField;
- Str255 fText;
- CharsHandle eChars;
- TEHandle theText;
- DecForm fpFormat;
- extended fpValue;
-
- if (efList != NIL) {
- theText = (*efList)->efText;
- if (theText != NIL) {
- TEDeactivate(theText);
- eChars = TEGetText(theText);
- BlockMove(*eChars,&fText[1],(*theText)->teLength);
- fText[0] = (*theText)->teLength;
-
- theField = GetIndexedField(efList,(*efList)->currentField);
- if (theField != NIL) {
- efFlags = GetEdFlags(theField);
-
- uLimit = (*theField)->upLimit;
- lLimit = (*theField)->lowLimit;
-
- if ((efFlags & (fieldNumeric + fieldFloatingPoint + fieldConvertTicks))
- == (fieldNumeric + fieldFloatingPoint + fieldConvertTicks)) {
- /* need floating point data */
-
- fpFormat.style = FIXEDDECIMAL;
- fpFormat.digits = 2;
-
- fpValue = GPCstr2num(&fText);
- if (incDecFlag) {
- fpValue -= 0.01667;
- if ((fpValue * 60) < lLimit)
- fpValue = (extended)lLimit/60;
- }
- else {
- fpValue += 0.01667;
- if ((fpValue * 60) > uLimit)
- fpValue = (extended)uLimit/60;
- }
-
- GPCnum2str(&fpFormat,fpValue,&fText);
- }
- else {
- StringToNum(&fText,&fValue);
-
- if (incDecFlag) {
- fValue --;
- if (fValue < (lLimit +1))
- fValue = lLimit;
- }
- else {
- fValue ++;
- if (fValue > (uLimit -1))
- fValue = uLimit;
- }
-
- NumToString(fValue,&fText);
- }
- TESetText(&fText[1],fText[0],theText);
- TEUpdate(&(*theText)->viewRect,theText);
- Delay(3,&tDelay);
- }
- TEActivate(theText);
- }
- }
- }
-
-
- void DrawEditFields(EFListHdl efList)
- {
- /* from the given record, draws the edit fields in the current port. The non-selected
- fields are updated using TextBox, the selected one updated using TEUpdate */
-
- EditFieldHdl temp;
- Rect tView,tFrame;
- int eSelect;
-
- if (efList != NIL) {
- temp = (*efList)->efListHead;
- eSelect = (*efList)->currentField;
-
- while(temp != NIL) {
- if ((*temp)->efID == eSelect) {
- tView = (*temp)->edViewRect;
- tFrame = tView;
- InsetRect(&tFrame,-3,-3);
- FrameRect(&tFrame);
- TEUpdate(&tView,(*efList)->efText);
- }
- else
- Draw1Field(temp);
-
- temp = (*temp)->nextField;
- }
- }
- }
-
-
- void SelectEditField(EFListHdl efList,int theIndex)
- {
- /* sets up the text record so that the indexed field is selected for editing. The
- text in the existing record is copied out to the field identified by the
- edFieldSelected value, the new text copied to the record, and the internal value
- updated */
-
- EditFieldHdl oldField,newField;
- TEHandle theEdRec;
- CharsHandle teText;
- int oldIndex;
- Rect eView;
- GrafPtr savePort;
-
- if (efList != NIL) {
- GetPort(&savePort);
- SetPort((*efList)->efOwner);
-
- theEdRec = (*efList)->efText;
- if (theEdRec != NIL) {
- oldIndex = (*efList)->currentField;
- oldField = GetIndexedField(efList,oldIndex);
- if ((oldField != NIL) && !((*oldField)->edFlags & fieldDataChanged)) {
- teText = TEGetText(theEdRec);
- HLock((Handle) oldField);
- BlockMove(*teText,&(*oldField)->edFieldText[1],(*theEdRec)->teLength);
- (*oldField)->edFieldText[0] = (*theEdRec)->teLength;
- HUnlock((Handle) oldField);
-
- }
- if ((oldIndex != theIndex) || ((*oldField)->edFlags & fieldDataChanged)) {
- TEDeactivate(theEdRec);
- newField = GetIndexedField(efList,theIndex);
- (*newField)->edFlags &= (0xFFFFFFFF - fieldDataChanged);
-
- if (newField != NIL) {
- (*efList)->currentField = theIndex;
- HLock((Handle) newField);
- TESetText(&(*newField)->edFieldText[1],
- (*newField)->edFieldText[0],theEdRec);
-
- HUnlock((Handle) newField);
-
- eView = (*newField)->edViewRect;
- (*theEdRec)->destRect = eView;
- (*theEdRec)->viewRect = eView;
- (*theEdRec)->destRect.right += 256;
-
- TECalText(theEdRec);
- Draw1Field(newField);
- }
- TEActivate(theEdRec);
- }
- }
- SetPort(savePort);
- }
- }
-
-
- int FindEditField(EFListHdl efList,Point mClick)
- {
- /* returns the ID number of the edit field containing the point, or zero if none do.
- This is used to hit test the edit fields when the window is clicked */
-
- EditFieldHdl eField;
- Rect efRect;
- int efClicked = 0;
-
- if (efList != NIL) {
- eField = (*efList)->efListHead;
-
- while (eField != NIL) {
- efRect = (*eField)->edViewRect;
- InsetRect(&efRect,-2,-2);
-
- if (PtInRect(mClick,&efRect)) {
- efClicked = (*eField)->efID;
- break;
- }
- else
- eField = (*eField)->nextField;
- }
- }
- return(efClicked);
- }
-
-
-
- void EFIdle(EFListHdl efList)
- {
- /* call frequently to blink the caret in edit fields */
-
-
- if (efList != NIL)
- TEIdle((*efList)->efText);
- }
-
-
- int CheckFieldLimits(EditFieldHdl theField,EFListHdl efList)
- {
- /* gets the current field value, if numeric, and checks it's current setting against
- the bounds. If outside, the value is changed to be pinned to the bounds */
-
- long fValue,efFlags,uLimit,lLimit;
- extended fValueFP;
- Str255 fText;
- int efsSave;
-
- if (theField != NIL && efList != NIL) {
- efFlags = GetEdFlags(theField);
- efsSave = (*efList)->currentField;
-
- if (efsSave == (*theField)->efID)
- SelectEditField(efList,efsSave); /* ensure field valid */
-
- if (efFlags & fieldNumeric) {
- if (efFlags & fieldFloatingPoint) {
- fValueFP = GetFPField(theField);
- if (efFlags & fieldConvertTicks)
- fValue = (fValueFP + 0.02) * 60;
- else
- fValue = fValueFP;
- }
- else {
- GetFieldText(theField,&fText);
- StringToNum(&fText,&fValue);
- }
-
- uLimit = (*theField)->upLimit;
- lLimit = (*theField)->lowLimit;
-
- if (fValue > uLimit) {
- fValue = uLimit;
- SetAndUpdateField(efList,(*theField)->efID,fValue);
- SysBeep(1);
- TESetSelect(0,32767,(*efList)->efText);
- return(FALSE);
- }
- else {
- if (fValue < lLimit) {
- fValue = lLimit;
- SetAndUpdateField(efList,(*theField)->efID,fValue);
- SysBeep(1);
- TESetSelect(0,32767,(*efList)->efText);
- return(FALSE);
- }
- }
- }
- }
- return(TRUE);
- }
-
-
-
-
- void KeyField(EFListHdl efList,char theKey)
- {
- /* passes keys to the current field. This examines the flags of the field to deter-
- mine what characters are filtered out. Control keys must already have been
- filtered and dealt with */
-
- int efSelect;
- EditFieldHdl eField;
- long efFlags;
- Boolean charInRange;
-
- if (efList != NIL) {
- efSelect = (*efList)->currentField;
- eField = GetIndexedField(efList,efSelect);
- efFlags = GetEdFlags(eField);
-
- if (theKey == 0x08 || (theKey >= 0x1C && theKey <= 0x1F))
- TEKey(theKey,(*efList)->efText);
- else {
- if (efFlags != fieldNoRestriction) {
- if (efFlags & fieldNumeric) {
- charInRange = !(theKey < 0x30 || theKey > 0x39);
- if (efFlags & fieldFloatingPoint)
- charInRange = charInRange || (theKey == 0x2E);
- }
- else {
- if (efFlags & fieldAlphabetic)
- charInRange = !(theKey < 0x41 || theKey > 0x7A);
- }
- if (charInRange)
- TEKey(theKey,(*efList)->efText);
- else
- SysBeep(1);
- }
- else
- TEKey(theKey,(*efList)->efText);
- }
- }
- }
-
-
- void SetAndUpdateField(EFListHdl efList,int theFieldID,long fValue)
- {
- /* given a fieldID number and a value, the value is converted to a string, set into
- the identified field (if it exists!) and the whole caboodle is updated. */
-
- Str255 fText;
- EditFieldHdl theField;
- int saveSelect;
- long efFlags;
- extended fValueFP;
-
- if (efList != NIL) {
- theField = GetIndexedField(efList,theFieldID);
- if (theField != NIL) {
- efFlags = GetEdFlags(theField);
- saveSelect = (*efList)->currentField;
-
- if ((efFlags & (fieldNumeric + fieldFloatingPoint))
- == (fieldNumeric + fieldFloatingPoint)) {
- if (efFlags & fieldConvertTicks)
- fValueFP = (extended)fValue/60;
- else
- fValueFP = (extended)fValue;
-
- SetFPField(theField,fValueFP,2);
- }
- else {
- NumToString(fValue,&fText);
- SetFieldText(theField,&fText);
- }
- (*efList)->currentField = 0; /* fudge the update mechanism! */
- SelectEditField(efList,theFieldID); /* keep text in order & update */
- SelectEditField(efList,saveSelect); /* restore the old field selection */
- }
- }
- }
-
-
-
-